﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ProxyViewModel;
using System.Reflection;
using System.ComponentModel;
using System.Windows.Input;

namespace AutoViewModel.Tests {
	[TestClass]
	public class TestContainedViewModelImplementation {
		public class ViewModelA {
			public virtual string Property1 {
				get;
				set;
			}
		}

		public class ViewModelB {
			private bool _wasPredicateCalled = false;

			public bool WasPredicateCalled {
				get { return _wasPredicateCalled; }
			}

			public virtual string Property2 {
				get;
				set;
			}

			public void TestCommand() {
			}

			public bool CanExecuteTestCommand() {
				return true;
			}
		}

		[TestMethod]
		public void TestInterfaceIsImplemented() {
			ViewModelA viewModel = ProxyViewModelFactory.CreateProxyViewModel<ViewModelA>();
			Assert.IsTrue(viewModel is IContainedViewModel, "IContainedViewModel is not implemented");
		}

		[TestMethod]
		public void TestSetMethod() {
			ViewModelA viewModel = ProxyViewModelFactory.CreateProxyViewModel<ViewModelA>();
			try {
				((IContainedViewModel)viewModel).SetParentViewModel(ProxyViewModelFactory.CreateProxyViewModel<ViewModelB>());
			}
			catch (Exception ex) {
				Assert.Fail(ex.ToString());
			}
		}

		[TestMethod]
		public void TestInvalidateParentViewModelGeneration() {
			ViewModelA viewModel = ProxyViewModelFactory.CreateProxyViewModel<ViewModelA>();
			MethodInfo method = viewModel.GetType().GetMethod("InvalidateParentViewModel", BindingFlags.Instance | BindingFlags.NonPublic);
			Assert.IsNotNull(method);
		}

		[TestMethod]
		public void TestInvalidateParentViewModelCanBeInvoked() {
			ViewModelB parentViewModel = ProxyViewModelFactory.CreateProxyViewModel<ViewModelB>();
			ViewModelA viewModel = ProxyViewModelFactory.CreateProxyViewModelWithParentViewModel<ViewModelA>(parentViewModel);

			bool canExecuteChangedCalled = false;
			ICommand testCommand = CommandsTesting.GetCommand(parentViewModel, "Test");

			testCommand.CanExecuteChanged += (s, e) => {
				canExecuteChangedCalled = true;
			};

			viewModel.Property1 = "New Value";
			Assert.IsTrue(canExecuteChangedCalled);
		}

	}
}
